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

Side by Side Diff: src/ia32/code-stubs-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/builtins-ia32.cc ('k') | src/ia32/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 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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 static Register registers[] = { eax }; 243 static Register registers[] = { eax };
244 descriptor->register_param_count_ = 1; 244 descriptor->register_param_count_ = 1;
245 descriptor->register_params_ = registers; 245 descriptor->register_params_ = registers;
246 descriptor->deoptimization_handler_ = 246 descriptor->deoptimization_handler_ =
247 FUNCTION_ADDR(ToBooleanIC_Miss); 247 FUNCTION_ADDR(ToBooleanIC_Miss);
248 descriptor->SetMissHandler( 248 descriptor->SetMissHandler(
249 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate)); 249 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate));
250 } 250 }
251 251
252 252
253 void UnaryOpStub::InitializeInterfaceDescriptor(
254 Isolate* isolate,
255 CodeStubInterfaceDescriptor* descriptor) {
256 static Register registers[] = { eax };
257 descriptor->register_param_count_ = 1;
258 descriptor->register_params_ = registers;
259 descriptor->deoptimization_handler_ =
260 FUNCTION_ADDR(UnaryOpIC_Miss);
261 }
262
263
253 void StoreGlobalStub::InitializeInterfaceDescriptor( 264 void StoreGlobalStub::InitializeInterfaceDescriptor(
254 Isolate* isolate, 265 Isolate* isolate,
255 CodeStubInterfaceDescriptor* descriptor) { 266 CodeStubInterfaceDescriptor* descriptor) {
256 static Register registers[] = { edx, ecx, eax }; 267 static Register registers[] = { edx, ecx, eax };
257 descriptor->register_param_count_ = 3; 268 descriptor->register_param_count_ = 3;
258 descriptor->register_params_ = registers; 269 descriptor->register_params_ = registers;
259 descriptor->deoptimization_handler_ = 270 descriptor->deoptimization_handler_ =
260 FUNCTION_ADDR(StoreIC_MissFromStubFailure); 271 FUNCTION_ADDR(StoreIC_MissFromStubFailure);
261 } 272 }
262 273
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 __ mov(FieldOperand(eax, Context::kLengthOffset), 504 __ mov(FieldOperand(eax, Context::kLengthOffset),
494 Immediate(Smi::FromInt(length))); 505 Immediate(Smi::FromInt(length)));
495 506
496 // If this block context is nested in the native context we get a smi 507 // If this block context is nested in the native context we get a smi
497 // sentinel instead of a function. The block context should get the 508 // sentinel instead of a function. The block context should get the
498 // canonical empty function of the native context as its closure which 509 // canonical empty function of the native context as its closure which
499 // we still have to look up. 510 // we still have to look up.
500 Label after_sentinel; 511 Label after_sentinel;
501 __ JumpIfNotSmi(ecx, &after_sentinel, Label::kNear); 512 __ JumpIfNotSmi(ecx, &after_sentinel, Label::kNear);
502 if (FLAG_debug_code) { 513 if (FLAG_debug_code) {
514 const char* message = "Expected 0 as a Smi sentinel";
503 __ cmp(ecx, 0); 515 __ cmp(ecx, 0);
504 __ Assert(equal, kExpected0AsASmiSentinel); 516 __ Assert(equal, message);
505 } 517 }
506 __ mov(ecx, GlobalObjectOperand()); 518 __ mov(ecx, GlobalObjectOperand());
507 __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset)); 519 __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset));
508 __ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX)); 520 __ mov(ecx, ContextOperand(ecx, Context::CLOSURE_INDEX));
509 __ bind(&after_sentinel); 521 __ bind(&after_sentinel);
510 522
511 // Set up the fixed slots. 523 // Set up the fixed slots.
512 __ mov(ContextOperand(eax, Context::CLOSURE_INDEX), ecx); 524 __ mov(ContextOperand(eax, Context::CLOSURE_INDEX), ecx);
513 __ mov(ContextOperand(eax, Context::PREVIOUS_INDEX), esi); 525 __ mov(ContextOperand(eax, Context::PREVIOUS_INDEX), esi);
514 __ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx); 526 __ mov(ContextOperand(eax, Context::EXTENSION_INDEX), ebx);
(...skipping 2935 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 __ mov(eax, Operand(esp, kJSRegExpOffset)); 3462 __ mov(eax, Operand(esp, kJSRegExpOffset));
3451 STATIC_ASSERT(kSmiTag == 0); 3463 STATIC_ASSERT(kSmiTag == 0);
3452 __ JumpIfSmi(eax, &runtime); 3464 __ JumpIfSmi(eax, &runtime);
3453 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx); 3465 __ CmpObjectType(eax, JS_REGEXP_TYPE, ecx);
3454 __ j(not_equal, &runtime); 3466 __ j(not_equal, &runtime);
3455 3467
3456 // Check that the RegExp has been compiled (data contains a fixed array). 3468 // Check that the RegExp has been compiled (data contains a fixed array).
3457 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); 3469 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset));
3458 if (FLAG_debug_code) { 3470 if (FLAG_debug_code) {
3459 __ test(ecx, Immediate(kSmiTagMask)); 3471 __ test(ecx, Immediate(kSmiTagMask));
3460 __ Check(not_zero, kUnexpectedTypeForRegExpDataFixedArrayExpected); 3472 __ Check(not_zero, "Unexpected type for RegExp data, FixedArray expected");
3461 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx); 3473 __ CmpObjectType(ecx, FIXED_ARRAY_TYPE, ebx);
3462 __ Check(equal, kUnexpectedTypeForRegExpDataFixedArrayExpected); 3474 __ Check(equal, "Unexpected type for RegExp data, FixedArray expected");
3463 } 3475 }
3464 3476
3465 // ecx: RegExp data (FixedArray) 3477 // ecx: RegExp data (FixedArray)
3466 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 3478 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
3467 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset)); 3479 __ mov(ebx, FieldOperand(ecx, JSRegExp::kDataTagOffset));
3468 __ cmp(ebx, Immediate(Smi::FromInt(JSRegExp::IRREGEXP))); 3480 __ cmp(ebx, Immediate(Smi::FromInt(JSRegExp::IRREGEXP)));
3469 __ j(not_equal, &runtime); 3481 __ j(not_equal, &runtime);
3470 3482
3471 // ecx: RegExp data (FixedArray) 3483 // ecx: RegExp data (FixedArray)
3472 // Check that the number of captures fit in the static offsets vector buffer. 3484 // Check that the number of captures fit in the static offsets vector buffer.
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3812 3824
3813 // (8) External string. Short external strings have been ruled out. 3825 // (8) External string. Short external strings have been ruled out.
3814 __ bind(&external_string); 3826 __ bind(&external_string);
3815 // Reload instance type. 3827 // Reload instance type.
3816 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3828 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
3817 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 3829 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
3818 if (FLAG_debug_code) { 3830 if (FLAG_debug_code) {
3819 // Assert that we do not have a cons or slice (indirect strings) here. 3831 // Assert that we do not have a cons or slice (indirect strings) here.
3820 // Sequential strings have already been ruled out. 3832 // Sequential strings have already been ruled out.
3821 __ test_b(ebx, kIsIndirectStringMask); 3833 __ test_b(ebx, kIsIndirectStringMask);
3822 __ Assert(zero, kExternalStringExpectedButNotFound); 3834 __ Assert(zero, "external string expected, but not found");
3823 } 3835 }
3824 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); 3836 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
3825 // Move the pointer so that offset-wise, it looks like a sequential string. 3837 // Move the pointer so that offset-wise, it looks like a sequential string.
3826 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 3838 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3827 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 3839 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
3828 STATIC_ASSERT(kTwoByteStringTag == 0); 3840 STATIC_ASSERT(kTwoByteStringTag == 0);
3829 // (8a) Is the external string one byte? If yes, go to (6). 3841 // (8a) Is the external string one byte? If yes, go to (6).
3830 __ test_b(ebx, kStringEncodingMask); 3842 __ test_b(ebx, kStringEncodingMask);
3831 __ j(not_zero, &seq_one_byte_string); // Goto (6). 3843 __ j(not_zero, &seq_one_byte_string); // Goto (6).
3832 3844
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
4307 ebx); 4319 ebx);
4308 } else { 4320 } else {
4309 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 4321 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
4310 edx, 4322 edx,
4311 eax, 4323 eax,
4312 ecx, 4324 ecx,
4313 ebx, 4325 ebx,
4314 edi); 4326 edi);
4315 } 4327 }
4316 #ifdef DEBUG 4328 #ifdef DEBUG
4317 __ Abort(kUnexpectedFallThroughFromStringComparison); 4329 __ Abort("Unexpected fall-through from string comparison");
4318 #endif 4330 #endif
4319 4331
4320 __ bind(&check_unequal_objects); 4332 __ bind(&check_unequal_objects);
4321 if (cc == equal && !strict()) { 4333 if (cc == equal && !strict()) {
4322 // Non-strict equality. Objects are unequal if 4334 // Non-strict equality. Objects are unequal if
4323 // they are both JSObjects and not undetectable, 4335 // they are both JSObjects and not undetectable,
4324 // and their pointers are different. 4336 // and their pointers are different.
4325 Label not_both_objects; 4337 Label not_both_objects;
4326 Label return_unequal; 4338 Label return_unequal;
4327 // At most one is a smi, so we can test for smi by adding the two. 4339 // At most one is a smi, so we can test for smi by adding the two.
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
5066 function); 5078 function);
5067 } else { 5079 } else {
5068 // The constants for the code patching are based on no push instructions 5080 // The constants for the code patching are based on no push instructions
5069 // at the call site. 5081 // at the call site.
5070 ASSERT(HasArgsInRegisters()); 5082 ASSERT(HasArgsInRegisters());
5071 // Get return address and delta to inlined map check. 5083 // Get return address and delta to inlined map check.
5072 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5084 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5073 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5085 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5074 if (FLAG_debug_code) { 5086 if (FLAG_debug_code) {
5075 __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1); 5087 __ cmpb(Operand(scratch, 0), kCmpEdiOperandByte1);
5076 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCmp1); 5088 __ Assert(equal, "InstanceofStub unexpected call site cache (cmp 1)");
5077 __ cmpb(Operand(scratch, 1), kCmpEdiOperandByte2); 5089 __ cmpb(Operand(scratch, 1), kCmpEdiOperandByte2);
5078 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheCmp2); 5090 __ Assert(equal, "InstanceofStub unexpected call site cache (cmp 2)");
5079 } 5091 }
5080 __ mov(scratch, Operand(scratch, kDeltaToCmpImmediate)); 5092 __ mov(scratch, Operand(scratch, kDeltaToCmpImmediate));
5081 __ mov(Operand(scratch, 0), map); 5093 __ mov(Operand(scratch, 0), map);
5082 } 5094 }
5083 5095
5084 // Loop through the prototype chain of the object looking for the function 5096 // Loop through the prototype chain of the object looking for the function
5085 // prototype. 5097 // prototype.
5086 __ mov(scratch, FieldOperand(map, Map::kPrototypeOffset)); 5098 __ mov(scratch, FieldOperand(map, Map::kPrototypeOffset));
5087 Label loop, is_instance, is_not_instance; 5099 Label loop, is_instance, is_not_instance;
5088 __ bind(&loop); 5100 __ bind(&loop);
(...skipping 12 matching lines...) Expand all
5101 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 5113 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
5102 __ mov(Operand::StaticArray(scratch, 5114 __ mov(Operand::StaticArray(scratch,
5103 times_pointer_size, roots_array_start), eax); 5115 times_pointer_size, roots_array_start), eax);
5104 } else { 5116 } else {
5105 // Get return address and delta to inlined map check. 5117 // Get return address and delta to inlined map check.
5106 __ mov(eax, factory->true_value()); 5118 __ mov(eax, factory->true_value());
5107 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5119 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5108 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5120 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5109 if (FLAG_debug_code) { 5121 if (FLAG_debug_code) {
5110 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 5122 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
5111 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 5123 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
5112 } 5124 }
5113 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 5125 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
5114 if (!ReturnTrueFalseObject()) { 5126 if (!ReturnTrueFalseObject()) {
5115 __ Set(eax, Immediate(0)); 5127 __ Set(eax, Immediate(0));
5116 } 5128 }
5117 } 5129 }
5118 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 5130 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
5119 5131
5120 __ bind(&is_not_instance); 5132 __ bind(&is_not_instance);
5121 if (!HasCallSiteInlineCheck()) { 5133 if (!HasCallSiteInlineCheck()) {
5122 __ Set(eax, Immediate(Smi::FromInt(1))); 5134 __ Set(eax, Immediate(Smi::FromInt(1)));
5123 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex)); 5135 __ mov(scratch, Immediate(Heap::kInstanceofCacheAnswerRootIndex));
5124 __ mov(Operand::StaticArray( 5136 __ mov(Operand::StaticArray(
5125 scratch, times_pointer_size, roots_array_start), eax); 5137 scratch, times_pointer_size, roots_array_start), eax);
5126 } else { 5138 } else {
5127 // Get return address and delta to inlined map check. 5139 // Get return address and delta to inlined map check.
5128 __ mov(eax, factory->false_value()); 5140 __ mov(eax, factory->false_value());
5129 __ mov(scratch, Operand(esp, 0 * kPointerSize)); 5141 __ mov(scratch, Operand(esp, 0 * kPointerSize));
5130 __ sub(scratch, Operand(esp, 1 * kPointerSize)); 5142 __ sub(scratch, Operand(esp, 1 * kPointerSize));
5131 if (FLAG_debug_code) { 5143 if (FLAG_debug_code) {
5132 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); 5144 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte);
5133 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); 5145 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)");
5134 } 5146 }
5135 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); 5147 __ mov(Operand(scratch, kDeltaToMovImmediate), eax);
5136 if (!ReturnTrueFalseObject()) { 5148 if (!ReturnTrueFalseObject()) {
5137 __ Set(eax, Immediate(Smi::FromInt(1))); 5149 __ Set(eax, Immediate(Smi::FromInt(1)));
5138 } 5150 }
5139 } 5151 }
5140 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); 5152 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
5141 5153
5142 Label object_not_null, object_not_null_or_smi; 5154 Label object_not_null, object_not_null_or_smi;
5143 __ bind(&not_js_object); 5155 __ bind(&not_js_object);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5236 masm, factory, object_, index_, result_, &call_runtime_); 5248 masm, factory, object_, index_, result_, &call_runtime_);
5237 5249
5238 __ SmiTag(result_); 5250 __ SmiTag(result_);
5239 __ bind(&exit_); 5251 __ bind(&exit_);
5240 } 5252 }
5241 5253
5242 5254
5243 void StringCharCodeAtGenerator::GenerateSlow( 5255 void StringCharCodeAtGenerator::GenerateSlow(
5244 MacroAssembler* masm, 5256 MacroAssembler* masm,
5245 const RuntimeCallHelper& call_helper) { 5257 const RuntimeCallHelper& call_helper) {
5246 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); 5258 __ Abort("Unexpected fallthrough to CharCodeAt slow case");
5247 5259
5248 // Index is not a smi. 5260 // Index is not a smi.
5249 __ bind(&index_not_smi_); 5261 __ bind(&index_not_smi_);
5250 // If index is a heap number, try converting it to an integer. 5262 // If index is a heap number, try converting it to an integer.
5251 __ CheckMap(index_, 5263 __ CheckMap(index_,
5252 masm->isolate()->factory()->heap_number_map(), 5264 masm->isolate()->factory()->heap_number_map(),
5253 index_not_number_, 5265 index_not_number_,
5254 DONT_DO_SMI_CHECK); 5266 DONT_DO_SMI_CHECK);
5255 call_helper.BeforeCall(masm); 5267 call_helper.BeforeCall(masm);
5256 __ push(object_); 5268 __ push(object_);
(...skipping 29 matching lines...) Expand all
5286 __ push(object_); 5298 __ push(object_);
5287 __ SmiTag(index_); 5299 __ SmiTag(index_);
5288 __ push(index_); 5300 __ push(index_);
5289 __ CallRuntime(Runtime::kStringCharCodeAt, 2); 5301 __ CallRuntime(Runtime::kStringCharCodeAt, 2);
5290 if (!result_.is(eax)) { 5302 if (!result_.is(eax)) {
5291 __ mov(result_, eax); 5303 __ mov(result_, eax);
5292 } 5304 }
5293 call_helper.AfterCall(masm); 5305 call_helper.AfterCall(masm);
5294 __ jmp(&exit_); 5306 __ jmp(&exit_);
5295 5307
5296 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); 5308 __ Abort("Unexpected fallthrough from CharCodeAt slow case");
5297 } 5309 }
5298 5310
5299 5311
5300 // ------------------------------------------------------------------------- 5312 // -------------------------------------------------------------------------
5301 // StringCharFromCodeGenerator 5313 // StringCharFromCodeGenerator
5302 5314
5303 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { 5315 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
5304 // Fast case of Heap::LookupSingleCharacterStringFromCode. 5316 // Fast case of Heap::LookupSingleCharacterStringFromCode.
5305 STATIC_ASSERT(kSmiTag == 0); 5317 STATIC_ASSERT(kSmiTag == 0);
5306 STATIC_ASSERT(kSmiShiftSize == 0); 5318 STATIC_ASSERT(kSmiShiftSize == 0);
(...skipping 14 matching lines...) Expand all
5321 FixedArray::kHeaderSize)); 5333 FixedArray::kHeaderSize));
5322 __ cmp(result_, factory->undefined_value()); 5334 __ cmp(result_, factory->undefined_value());
5323 __ j(equal, &slow_case_); 5335 __ j(equal, &slow_case_);
5324 __ bind(&exit_); 5336 __ bind(&exit_);
5325 } 5337 }
5326 5338
5327 5339
5328 void StringCharFromCodeGenerator::GenerateSlow( 5340 void StringCharFromCodeGenerator::GenerateSlow(
5329 MacroAssembler* masm, 5341 MacroAssembler* masm,
5330 const RuntimeCallHelper& call_helper) { 5342 const RuntimeCallHelper& call_helper) {
5331 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); 5343 __ Abort("Unexpected fallthrough to CharFromCode slow case");
5332 5344
5333 __ bind(&slow_case_); 5345 __ bind(&slow_case_);
5334 call_helper.BeforeCall(masm); 5346 call_helper.BeforeCall(masm);
5335 __ push(code_); 5347 __ push(code_);
5336 __ CallRuntime(Runtime::kCharFromCode, 1); 5348 __ CallRuntime(Runtime::kCharFromCode, 1);
5337 if (!result_.is(eax)) { 5349 if (!result_.is(eax)) {
5338 __ mov(result_, eax); 5350 __ mov(result_, eax);
5339 } 5351 }
5340 call_helper.AfterCall(masm); 5352 call_helper.AfterCall(masm);
5341 __ jmp(&exit_); 5353 __ jmp(&exit_);
5342 5354
5343 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 5355 __ Abort("Unexpected fallthrough from CharFromCode slow case");
5344 } 5356 }
5345 5357
5346 5358
5347 void StringAddStub::Generate(MacroAssembler* masm) { 5359 void StringAddStub::Generate(MacroAssembler* masm) {
5348 Label call_runtime, call_builtin; 5360 Label call_runtime, call_builtin;
5349 Builtins::JavaScript builtin_id = Builtins::ADD; 5361 Builtins::JavaScript builtin_id = Builtins::ADD;
5350 5362
5351 // Load the two arguments. 5363 // Load the two arguments.
5352 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. 5364 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
5353 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. 5365 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
(...skipping 2109 matching lines...) Expand 10 before | Expand all | Expand 10 after
7463 Label next; 7475 Label next;
7464 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7476 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7465 __ cmp(edx, kind); 7477 __ cmp(edx, kind);
7466 __ j(not_equal, &next); 7478 __ j(not_equal, &next);
7467 T stub(kind); 7479 T stub(kind);
7468 __ TailCallStub(&stub); 7480 __ TailCallStub(&stub);
7469 __ bind(&next); 7481 __ bind(&next);
7470 } 7482 }
7471 7483
7472 // If we reached this point there is a problem. 7484 // If we reached this point there is a problem.
7473 __ Abort(kUnexpectedElementsKindInArrayConstructor); 7485 __ Abort("Unexpected ElementsKind in array constructor");
7474 } 7486 }
7475 7487
7476 7488
7477 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { 7489 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
7478 // ebx - type info cell 7490 // ebx - type info cell
7479 // edx - kind 7491 // edx - kind
7480 // eax - number of arguments 7492 // eax - number of arguments
7481 // edi - constructor? 7493 // edi - constructor?
7482 // esp[0] - return address 7494 // esp[0] - return address
7483 // esp[4] - last argument 7495 // esp[4] - last argument
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
7526 Label next; 7538 Label next;
7527 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7539 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7528 __ cmp(edx, kind); 7540 __ cmp(edx, kind);
7529 __ j(not_equal, &next); 7541 __ j(not_equal, &next);
7530 ArraySingleArgumentConstructorStub stub(kind); 7542 ArraySingleArgumentConstructorStub stub(kind);
7531 __ TailCallStub(&stub); 7543 __ TailCallStub(&stub);
7532 __ bind(&next); 7544 __ bind(&next);
7533 } 7545 }
7534 7546
7535 // If we reached this point there is a problem. 7547 // If we reached this point there is a problem.
7536 __ Abort(kUnexpectedElementsKindInArrayConstructor); 7548 __ Abort("Unexpected ElementsKind in array constructor");
7537 } 7549 }
7538 7550
7539 7551
7540 template<class T> 7552 template<class T>
7541 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { 7553 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
7542 int to_index = GetSequenceIndexFromFastElementsKind( 7554 int to_index = GetSequenceIndexFromFastElementsKind(
7543 TERMINAL_FAST_ELEMENTS_KIND); 7555 TERMINAL_FAST_ELEMENTS_KIND);
7544 for (int i = 0; i <= to_index; ++i) { 7556 for (int i = 0; i <= to_index; ++i) {
7545 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); 7557 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
7546 T stub(kind); 7558 T stub(kind);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
7591 masm->isolate()); 7603 masm->isolate());
7592 7604
7593 if (FLAG_debug_code) { 7605 if (FLAG_debug_code) {
7594 // The array construct code is only set for the global and natives 7606 // The array construct code is only set for the global and natives
7595 // builtin Array functions which always have maps. 7607 // builtin Array functions which always have maps.
7596 7608
7597 // Initial map for the builtin Array function should be a map. 7609 // Initial map for the builtin Array function should be a map.
7598 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 7610 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
7599 // Will both indicate a NULL and a Smi. 7611 // Will both indicate a NULL and a Smi.
7600 __ test(ecx, Immediate(kSmiTagMask)); 7612 __ test(ecx, Immediate(kSmiTagMask));
7601 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); 7613 __ Assert(not_zero, "Unexpected initial map for Array function");
7602 __ CmpObjectType(ecx, MAP_TYPE, ecx); 7614 __ CmpObjectType(ecx, MAP_TYPE, ecx);
7603 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); 7615 __ Assert(equal, "Unexpected initial map for Array function");
7604 7616
7605 // We should either have undefined in ebx or a valid cell 7617 // We should either have undefined in ebx or a valid cell
7606 Label okay_here; 7618 Label okay_here;
7607 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); 7619 Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
7608 __ cmp(ebx, Immediate(undefined_sentinel)); 7620 __ cmp(ebx, Immediate(undefined_sentinel));
7609 __ j(equal, &okay_here); 7621 __ j(equal, &okay_here);
7610 __ cmp(FieldOperand(ebx, 0), Immediate(cell_map)); 7622 __ cmp(FieldOperand(ebx, 0), Immediate(cell_map));
7611 __ Assert(equal, kExpectedPropertyCellInRegisterEbx); 7623 __ Assert(equal, "Expected property cell in register ebx");
7612 __ bind(&okay_here); 7624 __ bind(&okay_here);
7613 } 7625 }
7614 7626
7615 Label no_info, switch_ready; 7627 Label no_info, switch_ready;
7616 // Get the elements kind and case on that. 7628 // Get the elements kind and case on that.
7617 __ cmp(ebx, Immediate(undefined_sentinel)); 7629 __ cmp(ebx, Immediate(undefined_sentinel));
7618 __ j(equal, &no_info); 7630 __ j(equal, &no_info);
7619 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset)); 7631 __ mov(edx, FieldOperand(ebx, Cell::kValueOffset));
7620 7632
7621 // The type cell may have undefined in its value. 7633 // The type cell may have undefined in its value.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
7705 // ----------------------------------- 7717 // -----------------------------------
7706 7718
7707 if (FLAG_debug_code) { 7719 if (FLAG_debug_code) {
7708 // The array construct code is only set for the global and natives 7720 // The array construct code is only set for the global and natives
7709 // builtin Array functions which always have maps. 7721 // builtin Array functions which always have maps.
7710 7722
7711 // Initial map for the builtin Array function should be a map. 7723 // Initial map for the builtin Array function should be a map.
7712 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 7724 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
7713 // Will both indicate a NULL and a Smi. 7725 // Will both indicate a NULL and a Smi.
7714 __ test(ecx, Immediate(kSmiTagMask)); 7726 __ test(ecx, Immediate(kSmiTagMask));
7715 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); 7727 __ Assert(not_zero, "Unexpected initial map for Array function");
7716 __ CmpObjectType(ecx, MAP_TYPE, ecx); 7728 __ CmpObjectType(ecx, MAP_TYPE, ecx);
7717 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); 7729 __ Assert(equal, "Unexpected initial map for Array function");
7718 } 7730 }
7719 7731
7720 // Figure out the right elements kind 7732 // Figure out the right elements kind
7721 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 7733 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
7722 7734
7723 // Load the map's "bit field 2" into |result|. We only need the first byte, 7735 // Load the map's "bit field 2" into |result|. We only need the first byte,
7724 // but the following masking takes care of that anyway. 7736 // but the following masking takes care of that anyway.
7725 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); 7737 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
7726 // Retrieve elements_kind from bit field 2. 7738 // Retrieve elements_kind from bit field 2.
7727 __ and_(ecx, Map::kElementsKindMask); 7739 __ and_(ecx, Map::kElementsKindMask);
7728 __ shr(ecx, Map::kElementsKindShift); 7740 __ shr(ecx, Map::kElementsKindShift);
7729 7741
7730 if (FLAG_debug_code) { 7742 if (FLAG_debug_code) {
7731 Label done; 7743 Label done;
7732 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 7744 __ cmp(ecx, Immediate(FAST_ELEMENTS));
7733 __ j(equal, &done); 7745 __ j(equal, &done);
7734 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS)); 7746 __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
7735 __ Assert(equal, 7747 __ Assert(equal,
7736 kInvalidElementsKindForInternalArrayOrInternalPackedArray); 7748 "Invalid ElementsKind for InternalArray or InternalPackedArray");
7737 __ bind(&done); 7749 __ bind(&done);
7738 } 7750 }
7739 7751
7740 Label fast_elements_case; 7752 Label fast_elements_case;
7741 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 7753 __ cmp(ecx, Immediate(FAST_ELEMENTS));
7742 __ j(equal, &fast_elements_case); 7754 __ j(equal, &fast_elements_case);
7743 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 7755 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
7744 7756
7745 __ bind(&fast_elements_case); 7757 __ bind(&fast_elements_case);
7746 GenerateCase(masm, FAST_ELEMENTS); 7758 GenerateCase(masm, FAST_ELEMENTS);
7747 } 7759 }
7748 7760
7749 7761
7750 #undef __ 7762 #undef __
7751 7763
7752 } } // namespace v8::internal 7764 } } // namespace v8::internal
7753 7765
7754 #endif // V8_TARGET_ARCH_IA32 7766 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698