| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "code-stubs.h" | 9 #include "code-stubs.h" |
| 10 #include "codegen.h" | 10 #include "codegen.h" |
| (...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 | 2207 |
| 2208 // Only the value field needs a write barrier, as the other values are in the | 2208 // Only the value field needs a write barrier, as the other values are in the |
| 2209 // root set. | 2209 // root set. |
| 2210 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2210 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2211 ecx, edx, kDontSaveFPRegs); | 2211 ecx, edx, kDontSaveFPRegs); |
| 2212 } | 2212 } |
| 2213 | 2213 |
| 2214 | 2214 |
| 2215 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2215 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2216 SetSourcePosition(prop->position()); | 2216 SetSourcePosition(prop->position()); |
| 2217 Literal* key = prop->key()->AsLiteral(); | 2217 Literal* key = prop->key()->AsStringLiteral(); |
| 2218 ASSERT(!key->value()->IsSmi()); | 2218 ASSERT(!key->value()->IsSmi()); |
| 2219 __ mov(ecx, Immediate(key->value())); | 2219 __ mov(ecx, Immediate(key->value())); |
| 2220 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2220 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2221 } | 2221 } |
| 2222 | 2222 |
| 2223 | 2223 |
| 2224 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2224 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2225 SetSourcePosition(prop->position()); | 2225 SetSourcePosition(prop->position()); |
| 2226 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2226 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2227 CallIC(ic, prop->PropertyFeedbackId()); | 2227 CallIC(ic, prop->PropertyFeedbackId()); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2354 Variable* var = expr->AsVariableProxy()->var(); | 2354 Variable* var = expr->AsVariableProxy()->var(); |
| 2355 EffectContext context(this); | 2355 EffectContext context(this); |
| 2356 EmitVariableAssignment(var, Token::ASSIGN); | 2356 EmitVariableAssignment(var, Token::ASSIGN); |
| 2357 break; | 2357 break; |
| 2358 } | 2358 } |
| 2359 case NAMED_PROPERTY: { | 2359 case NAMED_PROPERTY: { |
| 2360 __ push(eax); // Preserve value. | 2360 __ push(eax); // Preserve value. |
| 2361 VisitForAccumulatorValue(prop->obj()); | 2361 VisitForAccumulatorValue(prop->obj()); |
| 2362 __ mov(edx, eax); | 2362 __ mov(edx, eax); |
| 2363 __ pop(eax); // Restore value. | 2363 __ pop(eax); // Restore value. |
| 2364 __ mov(ecx, prop->key()->AsLiteral()->value()); | 2364 __ mov(ecx, prop->key()->AsStringLiteral()->value()); |
| 2365 CallStoreIC(); | 2365 CallStoreIC(); |
| 2366 break; | 2366 break; |
| 2367 } | 2367 } |
| 2368 case KEYED_PROPERTY: { | 2368 case KEYED_PROPERTY: { |
| 2369 __ push(eax); // Preserve value. | 2369 __ push(eax); // Preserve value. |
| 2370 VisitForStackValue(prop->obj()); | 2370 VisitForStackValue(prop->obj()); |
| 2371 VisitForAccumulatorValue(prop->key()); | 2371 VisitForAccumulatorValue(prop->key()); |
| 2372 __ mov(ecx, eax); | 2372 __ mov(ecx, eax); |
| 2373 __ pop(edx); // Receiver. | 2373 __ pop(edx); // Receiver. |
| 2374 __ pop(eax); // Restore value. | 2374 __ pop(eax); // Restore value. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 } | 2469 } |
| 2470 | 2470 |
| 2471 | 2471 |
| 2472 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2472 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2473 // Assignment to a property, using a named store IC. | 2473 // Assignment to a property, using a named store IC. |
| 2474 // eax : value | 2474 // eax : value |
| 2475 // esp[0] : receiver | 2475 // esp[0] : receiver |
| 2476 | 2476 |
| 2477 Property* prop = expr->target()->AsProperty(); | 2477 Property* prop = expr->target()->AsProperty(); |
| 2478 ASSERT(prop != NULL); | 2478 ASSERT(prop != NULL); |
| 2479 ASSERT(prop->key()->AsLiteral() != NULL); | 2479 ASSERT(prop->key()->AsStringLiteral() != NULL); |
| 2480 | 2480 |
| 2481 // Record source code position before IC call. | 2481 // Record source code position before IC call. |
| 2482 SetSourcePosition(expr->position()); | 2482 SetSourcePosition(expr->position()); |
| 2483 __ mov(ecx, prop->key()->AsLiteral()->value()); | 2483 __ mov(ecx, prop->key()->AsStringLiteral()->value()); |
| 2484 __ pop(edx); | 2484 __ pop(edx); |
| 2485 CallStoreIC(expr->AssignmentFeedbackId()); | 2485 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2486 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2486 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2487 context()->Plug(eax); | 2487 context()->Plug(eax); |
| 2488 } | 2488 } |
| 2489 | 2489 |
| 2490 | 2490 |
| 2491 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2491 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2492 // Assignment to a property, using a keyed store IC. | 2492 // Assignment to a property, using a keyed store IC. |
| 2493 // eax : value | 2493 // eax : value |
| (...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3300 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset)); | 3300 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset)); |
| 3301 | 3301 |
| 3302 __ bind(&done); | 3302 __ bind(&done); |
| 3303 context()->Plug(eax); | 3303 context()->Plug(eax); |
| 3304 } | 3304 } |
| 3305 | 3305 |
| 3306 | 3306 |
| 3307 void FullCodeGenerator::EmitDateField(CallRuntime* expr) { | 3307 void FullCodeGenerator::EmitDateField(CallRuntime* expr) { |
| 3308 ZoneList<Expression*>* args = expr->arguments(); | 3308 ZoneList<Expression*>* args = expr->arguments(); |
| 3309 ASSERT(args->length() == 2); | 3309 ASSERT(args->length() == 2); |
| 3310 ASSERT_NE(NULL, args->at(1)->AsLiteral()); | 3310 ASSERT_NE(NULL, args->at(1)->AsNumberLiteral()); |
| 3311 Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value())); | 3311 Smi* index = Smi::cast(*(args->at(1)->AsNumberLiteral()->value())); |
| 3312 | 3312 |
| 3313 VisitForAccumulatorValue(args->at(0)); // Load the object. | 3313 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 3314 | 3314 |
| 3315 Label runtime, done, not_date_object; | 3315 Label runtime, done, not_date_object; |
| 3316 Register object = eax; | 3316 Register object = eax; |
| 3317 Register result = eax; | 3317 Register result = eax; |
| 3318 Register scratch = ecx; | 3318 Register scratch = ecx; |
| 3319 | 3319 |
| 3320 __ JumpIfSmi(object, ¬_date_object); | 3320 __ JumpIfSmi(object, ¬_date_object); |
| 3321 __ CmpObjectType(object, JS_DATE_TYPE, scratch); | 3321 __ CmpObjectType(object, JS_DATE_TYPE, scratch); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3656 __ pop(ecx); | 3656 __ pop(ecx); |
| 3657 __ CallStub(&stub); | 3657 __ CallStub(&stub); |
| 3658 context()->Plug(eax); | 3658 context()->Plug(eax); |
| 3659 } | 3659 } |
| 3660 | 3660 |
| 3661 | 3661 |
| 3662 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { | 3662 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
| 3663 ZoneList<Expression*>* args = expr->arguments(); | 3663 ZoneList<Expression*>* args = expr->arguments(); |
| 3664 ASSERT_EQ(2, args->length()); | 3664 ASSERT_EQ(2, args->length()); |
| 3665 | 3665 |
| 3666 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3666 ASSERT_NE(NULL, args->at(0)->AsNumberLiteral()); |
| 3667 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); | 3667 int cache_id = Smi::cast(*(args->at(0)->AsNumberLiteral()->value()))->value(); |
| 3668 | 3668 |
| 3669 Handle<FixedArray> jsfunction_result_caches( | 3669 Handle<FixedArray> jsfunction_result_caches( |
| 3670 isolate()->native_context()->jsfunction_result_caches()); | 3670 isolate()->native_context()->jsfunction_result_caches()); |
| 3671 if (jsfunction_result_caches->length() <= cache_id) { | 3671 if (jsfunction_result_caches->length() <= cache_id) { |
| 3672 __ Abort(kAttemptToUseUndefinedCache); | 3672 __ Abort(kAttemptToUseUndefinedCache); |
| 3673 __ mov(eax, isolate()->factory()->undefined_value()); | 3673 __ mov(eax, isolate()->factory()->undefined_value()); |
| 3674 context()->Plug(eax); | 3674 context()->Plug(eax); |
| 3675 return; | 3675 return; |
| 3676 } | 3676 } |
| 3677 | 3677 |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4326 } | 4326 } |
| 4327 } else { | 4327 } else { |
| 4328 // Perform the assignment as if via '='. | 4328 // Perform the assignment as if via '='. |
| 4329 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4329 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4330 Token::ASSIGN); | 4330 Token::ASSIGN); |
| 4331 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4331 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4332 context()->Plug(eax); | 4332 context()->Plug(eax); |
| 4333 } | 4333 } |
| 4334 break; | 4334 break; |
| 4335 case NAMED_PROPERTY: { | 4335 case NAMED_PROPERTY: { |
| 4336 __ mov(ecx, prop->key()->AsLiteral()->value()); | 4336 __ mov(ecx, prop->key()->AsStringLiteral()->value()); |
| 4337 __ pop(edx); | 4337 __ pop(edx); |
| 4338 CallStoreIC(expr->CountStoreFeedbackId()); | 4338 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4339 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4339 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4340 if (expr->is_postfix()) { | 4340 if (expr->is_postfix()) { |
| 4341 if (!context()->IsEffect()) { | 4341 if (!context()->IsEffect()) { |
| 4342 context()->PlugTOS(); | 4342 context()->PlugTOS(); |
| 4343 } | 4343 } |
| 4344 } else { | 4344 } else { |
| 4345 context()->Plug(eax); | 4345 context()->Plug(eax); |
| 4346 } | 4346 } |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4803 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4803 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4804 Assembler::target_address_at(call_target_address, | 4804 Assembler::target_address_at(call_target_address, |
| 4805 unoptimized_code)); | 4805 unoptimized_code)); |
| 4806 return OSR_AFTER_STACK_CHECK; | 4806 return OSR_AFTER_STACK_CHECK; |
| 4807 } | 4807 } |
| 4808 | 4808 |
| 4809 | 4809 |
| 4810 } } // namespace v8::internal | 4810 } } // namespace v8::internal |
| 4811 | 4811 |
| 4812 #endif // V8_TARGET_ARCH_IA32 | 4812 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |