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

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

Issue 150093: X64: Implement unary subtraction, ObjectPair. 350 tests still fail. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 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/runtime.cc ('k') | no next file » | 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 2311 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 // Call the IC initialization code. 2322 // Call the IC initialization code.
2323 CodeForSourcePosition(node->position()); 2323 CodeForSourcePosition(node->position());
2324 Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT, 2324 Result result = frame_->CallCallIC(RelocInfo::CODE_TARGET_CONTEXT,
2325 arg_count, 2325 arg_count,
2326 loop_nesting()); 2326 loop_nesting());
2327 frame_->RestoreContextRegister(); 2327 frame_->RestoreContextRegister();
2328 // Replace the function on the stack with the result. 2328 // Replace the function on the stack with the result.
2329 frame_->SetElementAt(0, &result); 2329 frame_->SetElementAt(0, &result);
2330 } else if (var != NULL && var->slot() != NULL && 2330 } else if (var != NULL && var->slot() != NULL &&
2331 var->slot()->type() == Slot::LOOKUP) { 2331 var->slot()->type() == Slot::LOOKUP) {
2332 // TODO(X64): Enable calls of non-global functions.
2333 UNIMPLEMENTED();
2334 /*
2335 // ---------------------------------- 2332 // ----------------------------------
2336 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj 2333 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj
2337 // ---------------------------------- 2334 // ----------------------------------
2338 2335
2339 // Load the function from the context. Sync the frame so we can 2336 // Load the function from the context. Sync the frame so we can
2340 // push the arguments directly into place. 2337 // push the arguments directly into place.
2341 frame_->SyncRange(0, frame_->element_count() - 1); 2338 frame_->SyncRange(0, frame_->element_count() - 1);
2342 frame_->EmitPush(esi); 2339 frame_->EmitPush(rsi);
2343 frame_->EmitPush(Immediate(var->name())); 2340 frame_->EmitPush(var->name());
2344 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 2341 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
2345 // The runtime call returns a pair of values in rax and rdx. The 2342 // The runtime call returns a pair of values in rax and rdx. The
2346 // looked-up function is in rax and the receiver is in rdx. These 2343 // looked-up function is in rax and the receiver is in rdx. These
2347 // register references are not ref counted here. We spill them 2344 // register references are not ref counted here. We spill them
2348 // eagerly since they are arguments to an inevitable call (and are 2345 // eagerly since they are arguments to an inevitable call (and are
2349 // not sharable by the arguments). 2346 // not sharable by the arguments).
2350 ASSERT(!allocator()->is_used(rax)); 2347 ASSERT(!allocator()->is_used(rax));
2351 frame_->EmitPush(rax); 2348 frame_->EmitPush(rax);
2352 2349
2353 // Load the receiver. 2350 // Load the receiver.
2354 ASSERT(!allocator()->is_used(rdx)); 2351 ASSERT(!allocator()->is_used(rdx));
2355 frame_->EmitPush(rdx); 2352 frame_->EmitPush(rdx);
2356 2353
2357 // Call the function. 2354 // Call the function.
2358 CallWithArguments(args, node->position()); 2355 CallWithArguments(args, node->position());
2359 */
2360 } else if (property != NULL) { 2356 } else if (property != NULL) {
2361 // Check if the key is a literal string. 2357 // Check if the key is a literal string.
2362 Literal* literal = property->key()->AsLiteral(); 2358 Literal* literal = property->key()->AsLiteral();
2363 2359
2364 if (literal != NULL && literal->handle()->IsSymbol()) { 2360 if (literal != NULL && literal->handle()->IsSymbol()) {
2365 // ------------------------------------------------------------------ 2361 // ------------------------------------------------------------------
2366 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' 2362 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
2367 // ------------------------------------------------------------------ 2363 // ------------------------------------------------------------------
2368 2364
2369 // TODO(X64): Consider optimizing Function.prototype.apply calls 2365 // TODO(X64): Consider optimizing Function.prototype.apply calls
(...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after
3939 3935
3940 exit.Bind(); 3936 exit.Bind();
3941 } 3937 }
3942 } 3938 }
3943 3939
3944 3940
3945 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions( 3941 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions(
3946 Slot* slot, 3942 Slot* slot,
3947 TypeofState typeof_state, 3943 TypeofState typeof_state,
3948 JumpTarget* slow) { 3944 JumpTarget* slow) {
3949 UNIMPLEMENTED(); 3945 // Check that no extension objects have been created by calls to
3950 return Result(rax); 3946 // eval from the current scope to the global scope.
3947 Register context = rsi;
3948 Result tmp = allocator_->Allocate();
3949 ASSERT(tmp.is_valid()); // All non-reserved registers were available.
3950
3951 Scope* s = scope();
3952 while (s != NULL) {
3953 if (s->num_heap_slots() > 0) {
3954 if (s->calls_eval()) {
3955 // Check that extension is NULL.
3956 __ cmpq(ContextOperand(context, Context::EXTENSION_INDEX),
3957 Immediate(0));
3958 slow->Branch(not_equal, not_taken);
3959 }
3960 // Load next context in chain.
3961 __ movq(tmp.reg(), ContextOperand(context, Context::CLOSURE_INDEX));
3962 __ movq(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
3963 context = tmp.reg();
3964 }
3965 // If no outer scope calls eval, we do not need to check more
3966 // context extensions. If we have reached an eval scope, we check
3967 // all extensions from this point.
3968 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
3969 s = s->outer_scope();
3970 }
3971
3972 if (s->is_eval_scope()) {
3973 // Loop up the context chain. There is no frame effect so it is
3974 // safe to use raw labels here.
3975 Label next, fast;
3976 if (!context.is(tmp.reg())) {
3977 __ movq(tmp.reg(), context);
3978 }
3979 // Load map for comparison into register, outside loop.
3980 __ Move(kScratchRegister, Factory::global_context_map());
3981 __ bind(&next);
3982 // Terminate at global context.
3983 __ cmpq(kScratchRegister, FieldOperand(tmp.reg(), HeapObject::kMapOffset));
3984 __ j(equal, &fast);
3985 // Check that extension is NULL.
3986 __ cmpq(ContextOperand(tmp.reg(), Context::EXTENSION_INDEX), Immediate(0));
3987 slow->Branch(not_equal);
3988 // Load next context in chain.
3989 __ movq(tmp.reg(), ContextOperand(tmp.reg(), Context::CLOSURE_INDEX));
3990 __ movq(tmp.reg(), FieldOperand(tmp.reg(), JSFunction::kContextOffset));
3991 __ jmp(&next);
3992 __ bind(&fast);
3993 }
3994 tmp.Unuse();
3995
3996 // All extension objects were empty and it is safe to use a global
3997 // load IC call.
3998 LoadGlobal();
3999 frame_->Push(slot->var()->name());
4000 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
4001 ? RelocInfo::CODE_TARGET
4002 : RelocInfo::CODE_TARGET_CONTEXT;
4003 Result answer = frame_->CallLoadIC(mode);
4004 // A test rax instruction following the call signals that the inobject
4005 // property case was inlined. Ensure that there is not a test eax
4006 // instruction here.
4007 __ nop();
4008 // Discard the global object. The result is in answer.
4009 frame_->Drop();
4010 return answer;
3951 } 4011 }
3952 4012
3953 4013
3954 void CodeGenerator::LoadGlobal() { 4014 void CodeGenerator::LoadGlobal() {
3955 if (in_spilled_code()) { 4015 if (in_spilled_code()) {
3956 frame_->EmitPush(GlobalObject()); 4016 frame_->EmitPush(GlobalObject());
3957 } else { 4017 } else {
3958 Result temp = allocator_->Allocate(); 4018 Result temp = allocator_->Allocate();
3959 __ movq(temp.reg(), GlobalObject()); 4019 __ movq(temp.reg(), GlobalObject());
3960 frame_->Push(&temp); 4020 frame_->Push(&temp);
(...skipping 1417 matching lines...) Expand 10 before | Expand all | Expand 10 after
5378 break; 5438 break;
5379 } 5439 }
5380 if (answer_object == Heap::undefined_value()) { 5440 if (answer_object == Heap::undefined_value()) {
5381 return false; 5441 return false;
5382 } 5442 }
5383 frame_->Push(Handle<Object>(answer_object)); 5443 frame_->Push(Handle<Object>(answer_object));
5384 return true; 5444 return true;
5385 } 5445 }
5386 5446
5387 5447
5388
5389
5390 // End of CodeGenerator implementation. 5448 // End of CodeGenerator implementation.
5391 5449
5392 void UnarySubStub::Generate(MacroAssembler* masm) { 5450 void UnarySubStub::Generate(MacroAssembler* masm) {
5393 UNIMPLEMENTED(); 5451 Label slow;
5452 Label done;
5453 Label try_float;
5454
5455 // Check whether the value is a smi.
5456 __ testl(rax, Immediate(kSmiTagMask));
5457 // TODO(X64): Add inline code that handles floats, as on ia32 platform.
5458 __ j(not_zero, &slow);
5459
5460 // Enter runtime system if the value of the expression is zero
5461 // to make sure that we switch between 0 and -0.
5462 __ testq(rax, rax);
5463 __ j(zero, &slow);
5464
5465 // The value of the expression is a smi that is not zero. Try
5466 // optimistic subtraction '0 - value'.
5467 __ movq(rdx, rax);
5468 __ xor_(rax, rax);
5469 __ subl(rax, rdx);
5470 __ j(no_overflow, &done);
5471 // Restore rax and enter runtime system.
5472 __ movq(rax, rdx);
5473
5474 // Enter runtime system.
5475 __ bind(&slow);
5476 __ pop(rcx); // pop return address
5477 __ push(rax);
5478 __ push(rcx); // push return address
5479 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
5480
5481 __ bind(&done);
5482 __ StubReturn(1);
5394 } 5483 }
5395 5484
5396 5485
5397 void CompareStub::Generate(MacroAssembler* masm) { 5486 void CompareStub::Generate(MacroAssembler* masm) {
5398 Label call_builtin, done; 5487 Label call_builtin, done;
5399 5488
5400 // NOTICE! This code is only reached after a smi-fast-case check, so 5489 // NOTICE! This code is only reached after a smi-fast-case check, so
5401 // it is certain that at least one operand isn't a smi. 5490 // it is certain that at least one operand isn't a smi.
5402 5491
5403 if (cc_ == equal) { // Both strict and non-strict. 5492 if (cc_ == equal) { // Both strict and non-strict.
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after
6700 int CompareStub::MinorKey() { 6789 int CompareStub::MinorKey() {
6701 // Encode the two parameters in a unique 16 bit value. 6790 // Encode the two parameters in a unique 16 bit value.
6702 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 6791 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
6703 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 6792 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
6704 } 6793 }
6705 6794
6706 6795
6707 #undef __ 6796 #undef __
6708 6797
6709 } } // namespace v8::internal 6798 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698