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

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

Issue 22715004: Version 3.20.15 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Add TypedArray API and correctness patches r16033 and r16084 Created 7 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/deoptimizer-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 } 738 }
739 739
740 740
741 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 741 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
742 // The variable in the declaration always resides in the current context. 742 // The variable in the declaration always resides in the current context.
743 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 743 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
744 if (generate_debug_code_) { 744 if (generate_debug_code_) {
745 // Check that we're not inside a with or catch context. 745 // Check that we're not inside a with or catch context.
746 __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); 746 __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset));
747 __ cmp(ebx, isolate()->factory()->with_context_map()); 747 __ cmp(ebx, isolate()->factory()->with_context_map());
748 __ Check(not_equal, kDeclarationInWithContext); 748 __ Check(not_equal, "Declaration in with context.");
749 __ cmp(ebx, isolate()->factory()->catch_context_map()); 749 __ cmp(ebx, isolate()->factory()->catch_context_map());
750 __ Check(not_equal, kDeclarationInCatchContext); 750 __ Check(not_equal, "Declaration in catch context.");
751 } 751 }
752 } 752 }
753 753
754 754
755 void FullCodeGenerator::VisitVariableDeclaration( 755 void FullCodeGenerator::VisitVariableDeclaration(
756 VariableDeclaration* declaration) { 756 VariableDeclaration* declaration) {
757 // If it was not possible to allocate the variable at compile time, we 757 // If it was not possible to allocate the variable at compile time, we
758 // need to "declare" it at runtime to make sure it actually exists in the 758 // need to "declare" it at runtime to make sure it actually exists in the
759 // local context. 759 // local context.
760 VariableProxy* proxy = declaration->proxy(); 760 VariableProxy* proxy = declaration->proxy();
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 __ sub(edx, Immediate(1)); 2162 __ sub(edx, Immediate(1));
2163 __ j(carry, &call_resume); 2163 __ j(carry, &call_resume);
2164 __ push(ecx); 2164 __ push(ecx);
2165 __ jmp(&push_operand_holes); 2165 __ jmp(&push_operand_holes);
2166 __ bind(&call_resume); 2166 __ bind(&call_resume);
2167 __ push(ebx); 2167 __ push(ebx);
2168 __ push(result_register()); 2168 __ push(result_register());
2169 __ Push(Smi::FromInt(resume_mode)); 2169 __ Push(Smi::FromInt(resume_mode));
2170 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2170 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2171 // Not reached: the runtime call returns elsewhere. 2171 // Not reached: the runtime call returns elsewhere.
2172 __ Abort(kGeneratorFailedToResume); 2172 __ Abort("Generator failed to resume.");
2173 2173
2174 // Throw error if we attempt to operate on a running generator. 2174 // Throw error if we attempt to operate on a running generator.
2175 __ bind(&wrong_state); 2175 __ bind(&wrong_state);
2176 __ push(ebx); 2176 __ push(ebx);
2177 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2177 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2178 2178
2179 __ bind(&done); 2179 __ bind(&done);
2180 context()->Plug(result_register()); 2180 context()->Plug(result_register());
2181 } 2181 }
2182 2182
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 2461
2462 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2462 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) {
2463 // Assignment to var or initializing assignment to let/const 2463 // Assignment to var or initializing assignment to let/const
2464 // in harmony mode. 2464 // in harmony mode.
2465 if (var->IsStackAllocated() || var->IsContextSlot()) { 2465 if (var->IsStackAllocated() || var->IsContextSlot()) {
2466 MemOperand location = VarOperand(var, ecx); 2466 MemOperand location = VarOperand(var, ecx);
2467 if (generate_debug_code_ && op == Token::INIT_LET) { 2467 if (generate_debug_code_ && op == Token::INIT_LET) {
2468 // Check for an uninitialized let binding. 2468 // Check for an uninitialized let binding.
2469 __ mov(edx, location); 2469 __ mov(edx, location);
2470 __ cmp(edx, isolate()->factory()->the_hole_value()); 2470 __ cmp(edx, isolate()->factory()->the_hole_value());
2471 __ Check(equal, kLetBindingReInitialization); 2471 __ Check(equal, "Let binding re-initialization.");
2472 } 2472 }
2473 // Perform the assignment. 2473 // Perform the assignment.
2474 __ mov(location, eax); 2474 __ mov(location, eax);
2475 if (var->IsContextSlot()) { 2475 if (var->IsContextSlot()) {
2476 __ mov(edx, eax); 2476 __ mov(edx, eax);
2477 int offset = Context::SlotOffset(var->index()); 2477 int offset = Context::SlotOffset(var->index());
2478 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2478 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
2479 } 2479 }
2480 } else { 2480 } else {
2481 ASSERT(var->IsLookupSlot()); 2481 ASSERT(var->IsLookupSlot());
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
3423 __ bind(&done); 3423 __ bind(&done);
3424 context()->Plug(result); 3424 context()->Plug(result);
3425 } 3425 }
3426 3426
3427 3427
3428 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string, 3428 void FullCodeGenerator::EmitSeqStringSetCharCheck(Register string,
3429 Register index, 3429 Register index,
3430 Register value, 3430 Register value,
3431 uint32_t encoding_mask) { 3431 uint32_t encoding_mask) {
3432 __ test(index, Immediate(kSmiTagMask)); 3432 __ test(index, Immediate(kSmiTagMask));
3433 __ Check(zero, kNonSmiIndex); 3433 __ Check(zero, "Non-smi index");
3434 __ test(value, Immediate(kSmiTagMask)); 3434 __ test(value, Immediate(kSmiTagMask));
3435 __ Check(zero, kNonSmiValue); 3435 __ Check(zero, "Non-smi value");
3436 3436
3437 __ cmp(index, FieldOperand(string, String::kLengthOffset)); 3437 __ cmp(index, FieldOperand(string, String::kLengthOffset));
3438 __ Check(less, kIndexIsTooLarge); 3438 __ Check(less, "Index is too large");
3439 3439
3440 __ cmp(index, Immediate(Smi::FromInt(0))); 3440 __ cmp(index, Immediate(Smi::FromInt(0)));
3441 __ Check(greater_equal, kIndexIsNegative); 3441 __ Check(greater_equal, "Index is negative");
3442 3442
3443 __ push(value); 3443 __ push(value);
3444 __ mov(value, FieldOperand(string, HeapObject::kMapOffset)); 3444 __ mov(value, FieldOperand(string, HeapObject::kMapOffset));
3445 __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset)); 3445 __ movzx_b(value, FieldOperand(value, Map::kInstanceTypeOffset));
3446 3446
3447 __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 3447 __ and_(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
3448 __ cmp(value, Immediate(encoding_mask)); 3448 __ cmp(value, Immediate(encoding_mask));
3449 __ Check(equal, kUnexpectedStringType); 3449 __ Check(equal, "Unexpected string type");
3450 __ pop(value); 3450 __ pop(value);
3451 } 3451 }
3452 3452
3453 3453
3454 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3454 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3455 ZoneList<Expression*>* args = expr->arguments(); 3455 ZoneList<Expression*>* args = expr->arguments();
3456 ASSERT_EQ(3, args->length()); 3456 ASSERT_EQ(3, args->length());
3457 3457
3458 Register string = eax; 3458 Register string = eax;
3459 Register index = ebx; 3459 Register index = ebx;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
3811 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3811 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
3812 ZoneList<Expression*>* args = expr->arguments(); 3812 ZoneList<Expression*>* args = expr->arguments();
3813 ASSERT_EQ(2, args->length()); 3813 ASSERT_EQ(2, args->length());
3814 3814
3815 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 3815 ASSERT_NE(NULL, args->at(0)->AsLiteral());
3816 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); 3816 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
3817 3817
3818 Handle<FixedArray> jsfunction_result_caches( 3818 Handle<FixedArray> jsfunction_result_caches(
3819 isolate()->native_context()->jsfunction_result_caches()); 3819 isolate()->native_context()->jsfunction_result_caches());
3820 if (jsfunction_result_caches->length() <= cache_id) { 3820 if (jsfunction_result_caches->length() <= cache_id) {
3821 __ Abort(kAttemptToUseUndefinedCache); 3821 __ Abort("Attempt to use undefined cache.");
3822 __ mov(eax, isolate()->factory()->undefined_value()); 3822 __ mov(eax, isolate()->factory()->undefined_value());
3823 context()->Plug(eax); 3823 context()->Plug(eax);
3824 return; 3824 return;
3825 } 3825 }
3826 3826
3827 VisitForAccumulatorValue(args->at(1)); 3827 VisitForAccumulatorValue(args->at(1));
3828 3828
3829 Register key = eax; 3829 Register key = eax;
3830 Register cache = ebx; 3830 Register cache = ebx;
3831 Register tmp = ecx; 3831 Register tmp = ecx;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3993 3993
3994 // Check that all array elements are sequential ASCII strings, and 3994 // Check that all array elements are sequential ASCII strings, and
3995 // accumulate the sum of their lengths, as a smi-encoded value. 3995 // accumulate the sum of their lengths, as a smi-encoded value.
3996 __ Set(index, Immediate(0)); 3996 __ Set(index, Immediate(0));
3997 __ Set(string_length, Immediate(0)); 3997 __ Set(string_length, Immediate(0));
3998 // Loop condition: while (index < length). 3998 // Loop condition: while (index < length).
3999 // Live loop registers: index, array_length, string, 3999 // Live loop registers: index, array_length, string,
4000 // scratch, string_length, elements. 4000 // scratch, string_length, elements.
4001 if (generate_debug_code_) { 4001 if (generate_debug_code_) {
4002 __ cmp(index, array_length); 4002 __ cmp(index, array_length);
4003 __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); 4003 __ Assert(less, "No empty arrays here in EmitFastAsciiArrayJoin");
4004 } 4004 }
4005 __ bind(&loop); 4005 __ bind(&loop);
4006 __ mov(string, FieldOperand(elements, 4006 __ mov(string, FieldOperand(elements,
4007 index, 4007 index,
4008 times_pointer_size, 4008 times_pointer_size,
4009 FixedArray::kHeaderSize)); 4009 FixedArray::kHeaderSize));
4010 __ JumpIfSmi(string, &bailout); 4010 __ JumpIfSmi(string, &bailout);
4011 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); 4011 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
4012 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 4012 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
4013 __ and_(scratch, Immediate( 4013 __ and_(scratch, Immediate(
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
4340 case Token::TYPEOF: { 4340 case Token::TYPEOF: {
4341 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 4341 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
4342 { StackValueContext context(this); 4342 { StackValueContext context(this);
4343 VisitForTypeofValue(expr->expression()); 4343 VisitForTypeofValue(expr->expression());
4344 } 4344 }
4345 __ CallRuntime(Runtime::kTypeof, 1); 4345 __ CallRuntime(Runtime::kTypeof, 1);
4346 context()->Plug(eax); 4346 context()->Plug(eax);
4347 break; 4347 break;
4348 } 4348 }
4349 4349
4350 case Token::SUB:
4351 EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
4352 break;
4353
4354 case Token::BIT_NOT:
4355 EmitUnaryOperation(expr, "[ UnaryOperation (BIT_NOT)");
4356 break;
4357
4350 default: 4358 default:
4351 UNREACHABLE(); 4359 UNREACHABLE();
4352 } 4360 }
4353 } 4361 }
4354 4362
4355 4363
4364 void FullCodeGenerator::EmitUnaryOperation(UnaryOperation* expr,
4365 const char* comment) {
4366 Comment cmt(masm_, comment);
4367 UnaryOpStub stub(expr->op());
4368 // UnaryOpStub expects the argument to be in the
4369 // accumulator register eax.
4370 VisitForAccumulatorValue(expr->expression());
4371 SetSourcePosition(expr->position());
4372 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET,
4373 expr->UnaryOperationFeedbackId());
4374 context()->Plug(eax);
4375 }
4376
4377
4356 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4378 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4357 Comment cmnt(masm_, "[ CountOperation"); 4379 Comment cmnt(masm_, "[ CountOperation");
4358 SetSourcePosition(expr->position()); 4380 SetSourcePosition(expr->position());
4359 4381
4360 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 4382 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
4361 // as the left-hand side. 4383 // as the left-hand side.
4362 if (!expr->expression()->IsValidLeftHandSide()) { 4384 if (!expr->expression()->IsValidLeftHandSide()) {
4363 VisitForEffect(expr->expression()); 4385 VisitForEffect(expr->expression());
4364 return; 4386 return;
4365 } 4387 }
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
4894 *stack_depth = 0; 4916 *stack_depth = 0;
4895 *context_length = 0; 4917 *context_length = 0;
4896 return previous_; 4918 return previous_;
4897 } 4919 }
4898 4920
4899 #undef __ 4921 #undef __
4900 4922
4901 } } // namespace v8::internal 4923 } } // namespace v8::internal
4902 4924
4903 #endif // V8_TARGET_ARCH_IA32 4925 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/deoptimizer-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698