Chromium Code Reviews

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6717018: Introduce accessors on builtins instance (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 256 matching lines...)
267 Register prototype) { 267 Register prototype) {
268 __ LoadGlobalFunction(index, prototype); 268 __ LoadGlobalFunction(index, prototype);
269 __ LoadGlobalFunctionInitialMap(prototype, prototype); 269 __ LoadGlobalFunctionInitialMap(prototype, prototype);
270 // Load the prototype from the initial map. 270 // Load the prototype from the initial map.
271 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 271 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
272 } 272 }
273 273
274 274
275 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 275 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
276 MacroAssembler* masm, int index, Register prototype, Label* miss) { 276 MacroAssembler* masm, int index, Register prototype, Label* miss) {
277 Isolate* isolate = masm->isolate();
277 // Check we're still in the same context. 278 // Check we're still in the same context.
278 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), 279 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
279 Isolate::Current()->global()); 280 isolate->global());
280 __ j(not_equal, miss); 281 __ j(not_equal, miss);
281 // Get the global function with the given index. 282 // Get the global function with the given index.
282 JSFunction* function = JSFunction::cast( 283 JSFunction* function =
283 Isolate::Current()->global_context()->get(index)); 284 JSFunction::cast(isolate->global_context()->get(index));
284 // Load its initial map. The global functions all have initial maps. 285 // Load its initial map. The global functions all have initial maps.
285 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); 286 __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
286 // Load the prototype from the initial map. 287 // Load the prototype from the initial map.
287 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 288 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
288 } 289 }
289 290
290 291
291 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 292 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
292 Register receiver, 293 Register receiver,
293 Register scratch, 294 Register scratch,
(...skipping 445 matching lines...)
739 StubCompiler* stub_compiler_; 740 StubCompiler* stub_compiler_;
740 const ParameterCount& arguments_; 741 const ParameterCount& arguments_;
741 Register name_; 742 Register name_;
742 }; 743 };
743 744
744 745
745 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 746 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
746 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 747 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
747 Code* code = NULL; 748 Code* code = NULL;
748 if (kind == Code::LOAD_IC) { 749 if (kind == Code::LOAD_IC) {
749 code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss); 750 code = masm->isolate()->builtins()->builtin(Builtins::LoadIC_Miss);
750 } else { 751 } else {
751 code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss); 752 code = masm->isolate()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
752 } 753 }
753 754
754 Handle<Code> ic(code); 755 Handle<Code> ic(code);
755 __ jmp(ic, RelocInfo::CODE_TARGET); 756 __ jmp(ic, RelocInfo::CODE_TARGET);
756 } 757 }
757 758
758 759
759 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 760 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
760 // but may be destroyed if store is successful. 761 // but may be destroyed if store is successful.
761 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 762 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
(...skipping 589 matching lines...)
1351 __ j(not_equal, miss, not_taken); 1352 __ j(not_equal, miss, not_taken);
1352 } else { 1353 } else {
1353 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1354 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1354 __ j(not_equal, miss, not_taken); 1355 __ j(not_equal, miss, not_taken);
1355 } 1356 }
1356 } 1357 }
1357 1358
1358 1359
1359 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1360 MaybeObject* CallStubCompiler::GenerateMissBranch() {
1360 MaybeObject* maybe_obj = 1361 MaybeObject* maybe_obj =
1361 Isolate::Current()->stub_cache()->ComputeCallMiss( 1362 masm()->isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1362 arguments().immediate(), kind_); 1363 kind_);
1363 Object* obj; 1364 Object* obj;
1364 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1365 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1365 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1366 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1366 return obj; 1367 return obj;
1367 } 1368 }
1368 1369
1369 1370
1370 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1371 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField(
1371 JSObject* object, 1372 JSObject* object,
1372 JSObject* holder, 1373 JSObject* holder,
(...skipping 531 matching lines...)
1904 JSFunction* function, 1905 JSFunction* function,
1905 String* name) { 1906 String* name) {
1906 // ----------- S t a t e ------------- 1907 // ----------- S t a t e -------------
1907 // -- ecx : name 1908 // -- ecx : name
1908 // -- esp[0] : return address 1909 // -- esp[0] : return address
1909 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1910 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1910 // -- ... 1911 // -- ...
1911 // -- esp[(argc + 1) * 4] : receiver 1912 // -- esp[(argc + 1) * 4] : receiver
1912 // ----------------------------------- 1913 // -----------------------------------
1913 1914
1914 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) 1915 if (masm()->isolate()->cpu_features()->IsSupported(SSE2))
1915 return HEAP->undefined_value(); 1916 return HEAP->undefined_value();
1916 CpuFeatures::Scope use_sse2(SSE2); 1917 CpuFeatures::Scope use_sse2(SSE2);
1917 1918
1918 const int argc = arguments().immediate(); 1919 const int argc = arguments().immediate();
1919 1920
1920 // If the object is not a JSObject or we got an unexpected number of 1921 // If the object is not a JSObject or we got an unexpected number of
1921 // arguments, bail out to the regular call. 1922 // arguments, bail out to the regular call.
1922 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); 1923 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
1923 1924
1924 Label miss; 1925 Label miss;
(...skipping 547 matching lines...)
2472 GenerateStoreField(masm(), 2473 GenerateStoreField(masm(),
2473 object, 2474 object,
2474 index, 2475 index,
2475 transition, 2476 transition,
2476 edx, ecx, ebx, 2477 edx, ecx, ebx,
2477 &miss); 2478 &miss);
2478 2479
2479 // Handle store cache miss. 2480 // Handle store cache miss.
2480 __ bind(&miss); 2481 __ bind(&miss);
2481 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2482 __ mov(ecx, Immediate(Handle<String>(name))); // restore name
2482 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2483 Handle<Code> ic =
2483 Builtins::StoreIC_Miss)); 2484 Builtins::builtin(Builtins::StoreIC_Miss, masm()->isolate());
2484 __ jmp(ic, RelocInfo::CODE_TARGET); 2485 __ jmp(ic, RelocInfo::CODE_TARGET);
2485 2486
2486 // Return the generated code. 2487 // Return the generated code.
2487 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2488 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2488 } 2489 }
2489 2490
2490 2491
2491 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2492 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
2492 AccessorInfo* callback, 2493 AccessorInfo* callback,
2493 String* name) { 2494 String* name) {
(...skipping 31 matching lines...)
2525 __ push(ebx); // restore return address 2526 __ push(ebx); // restore return address
2526 2527
2527 // Do tail-call to the runtime system. 2528 // Do tail-call to the runtime system.
2528 Isolate* isolate = masm()->isolate(); 2529 Isolate* isolate = masm()->isolate();
2529 ExternalReference store_callback_property = 2530 ExternalReference store_callback_property =
2530 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate); 2531 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate);
2531 __ TailCallExternalReference(store_callback_property, 4, 1); 2532 __ TailCallExternalReference(store_callback_property, 4, 1);
2532 2533
2533 // Handle store cache miss. 2534 // Handle store cache miss.
2534 __ bind(&miss); 2535 __ bind(&miss);
2535 Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss)); 2536 Handle<Code> ic = Builtins::builtin(Builtins::StoreIC_Miss, isolate);
2536 __ jmp(ic, RelocInfo::CODE_TARGET); 2537 __ jmp(ic, RelocInfo::CODE_TARGET);
2537 2538
2538 // Return the generated code. 2539 // Return the generated code.
2539 return GetCode(CALLBACKS, name); 2540 return GetCode(CALLBACKS, name);
2540 } 2541 }
2541 2542
2542 2543
2543 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2544 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
2544 String* name) { 2545 String* name) {
2545 // ----------- S t a t e ------------- 2546 // ----------- S t a t e -------------
(...skipping 30 matching lines...)
2576 __ push(ebx); // restore return address 2577 __ push(ebx); // restore return address
2577 2578
2578 // Do tail-call to the runtime system. 2579 // Do tail-call to the runtime system.
2579 Isolate* isolate = masm()->isolate(); 2580 Isolate* isolate = masm()->isolate();
2580 ExternalReference store_ic_property = 2581 ExternalReference store_ic_property =
2581 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate); 2582 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate);
2582 __ TailCallExternalReference(store_ic_property, 4, 1); 2583 __ TailCallExternalReference(store_ic_property, 4, 1);
2583 2584
2584 // Handle store cache miss. 2585 // Handle store cache miss.
2585 __ bind(&miss); 2586 __ bind(&miss);
2586 Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss)); 2587 Handle<Code> ic = Builtins::builtin(Builtins::StoreIC_Miss, isolate);
2587 __ jmp(ic, RelocInfo::CODE_TARGET); 2588 __ jmp(ic, RelocInfo::CODE_TARGET);
2588 2589
2589 // Return the generated code. 2590 // Return the generated code.
2590 return GetCode(INTERCEPTOR, name); 2591 return GetCode(INTERCEPTOR, name);
2591 } 2592 }
2592 2593
2593 2594
2594 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2595 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
2595 JSGlobalPropertyCell* cell, 2596 JSGlobalPropertyCell* cell,
2596 String* name) { 2597 String* name) {
(...skipping 28 matching lines...)
2625 // Store the value in the cell. 2626 // Store the value in the cell.
2626 __ mov(cell_operand, eax); 2627 __ mov(cell_operand, eax);
2627 2628
2628 // Return the value (register eax). 2629 // Return the value (register eax).
2629 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1); 2630 __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
2630 __ ret(0); 2631 __ ret(0);
2631 2632
2632 // Handle store cache miss. 2633 // Handle store cache miss.
2633 __ bind(&miss); 2634 __ bind(&miss);
2634 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1); 2635 __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
2635 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2636 Handle<Code> ic =
2636 Builtins::StoreIC_Miss)); 2637 Builtins::builtin(Builtins::StoreIC_Miss, masm()->isolate());
2637 __ jmp(ic, RelocInfo::CODE_TARGET); 2638 __ jmp(ic, RelocInfo::CODE_TARGET);
2638 2639
2639 // Return the generated code. 2640 // Return the generated code.
2640 return GetCode(NORMAL, name); 2641 return GetCode(NORMAL, name);
2641 } 2642 }
2642 2643
2643 2644
2644 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2645 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
2645 int index, 2646 int index,
2646 Map* transition, 2647 Map* transition,
(...skipping 16 matching lines...)
2663 GenerateStoreField(masm(), 2664 GenerateStoreField(masm(),
2664 object, 2665 object,
2665 index, 2666 index,
2666 transition, 2667 transition,
2667 edx, ecx, ebx, 2668 edx, ecx, ebx,
2668 &miss); 2669 &miss);
2669 2670
2670 // Handle store cache miss. 2671 // Handle store cache miss.
2671 __ bind(&miss); 2672 __ bind(&miss);
2672 __ DecrementCounter(COUNTERS->keyed_store_field(), 1); 2673 __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
2673 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 2674 Handle<Code> ic =
2674 Builtins::KeyedStoreIC_Miss)); 2675 Builtins::builtin(Builtins::KeyedStoreIC_Miss, masm()->isolate());
2675 __ jmp(ic, RelocInfo::CODE_TARGET); 2676 __ jmp(ic, RelocInfo::CODE_TARGET);
2676 2677
2677 // Return the generated code. 2678 // Return the generated code.
2678 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2679 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2679 } 2680 }
2680 2681
2681 2682
2682 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2683 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
2683 JSObject* receiver) { 2684 JSObject* receiver) {
2684 // ----------- S t a t e ------------- 2685 // ----------- S t a t e -------------
(...skipping 36 matching lines...)
2721 // the value in register eax. 2722 // the value in register eax.
2722 __ mov(edx, Operand(eax)); 2723 __ mov(edx, Operand(eax));
2723 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2724 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2724 __ RecordWrite(edi, 0, edx, ecx); 2725 __ RecordWrite(edi, 0, edx, ecx);
2725 2726
2726 // Done. 2727 // Done.
2727 __ ret(0); 2728 __ ret(0);
2728 2729
2729 // Handle store cache miss. 2730 // Handle store cache miss.
2730 __ bind(&miss); 2731 __ bind(&miss);
2731 Handle<Code> ic( 2732 Handle<Code> ic =
2732 Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss)); 2733 Builtins::builtin(Builtins::KeyedStoreIC_Miss, masm()->isolate());
2733 __ jmp(ic, RelocInfo::CODE_TARGET); 2734 __ jmp(ic, RelocInfo::CODE_TARGET);
2734 2735
2735 // Return the generated code. 2736 // Return the generated code.
2736 return GetCode(NORMAL, NULL); 2737 return GetCode(NORMAL, NULL);
2737 } 2738 }
2738 2739
2739 2740
2740 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2741 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2741 JSObject* object, 2742 JSObject* object,
2742 JSObject* last) { 2743 JSObject* last) {
(...skipping 520 matching lines...)
3263 // depending on the this.x = ...; assignment in the function. 3264 // depending on the this.x = ...; assignment in the function.
3264 SharedFunctionInfo* shared = function->shared(); 3265 SharedFunctionInfo* shared = function->shared();
3265 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3266 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3266 if (shared->IsThisPropertyAssignmentArgument(i)) { 3267 if (shared->IsThisPropertyAssignmentArgument(i)) {
3267 // Check if the argument assigned to the property is actually passed. 3268 // Check if the argument assigned to the property is actually passed.
3268 // If argument is not passed the property is set to undefined, 3269 // If argument is not passed the property is set to undefined,
3269 // otherwise find it on the stack. 3270 // otherwise find it on the stack.
3270 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3271 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3271 __ mov(ebx, edi); 3272 __ mov(ebx, edi);
3272 __ cmp(eax, arg_number); 3273 __ cmp(eax, arg_number);
3273 if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) { 3274 if (masm()->isolate()->cpu_features()->IsSupported(CMOV)) {
3274 CpuFeatures::Scope use_cmov(CMOV); 3275 CpuFeatures::Scope use_cmov(CMOV);
3275 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); 3276 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
3276 } else { 3277 } else {
3277 Label not_passed; 3278 Label not_passed;
3278 __ j(below_equal, &not_passed); 3279 __ j(below_equal, &not_passed);
3279 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); 3280 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
3280 __ bind(&not_passed); 3281 __ bind(&not_passed);
3281 } 3282 }
3282 // Store value in the property. 3283 // Store value in the property.
3283 __ mov(Operand(edx, i * kPointerSize), ebx); 3284 __ mov(Operand(edx, i * kPointerSize), ebx);
(...skipping 21 matching lines...)
3305 __ pop(ecx); 3306 __ pop(ecx);
3306 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3307 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3307 __ push(ecx); 3308 __ push(ecx);
3308 __ IncrementCounter(COUNTERS->constructed_objects(), 1); 3309 __ IncrementCounter(COUNTERS->constructed_objects(), 1);
3309 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1); 3310 __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
3310 __ ret(0); 3311 __ ret(0);
3311 3312
3312 // Jump to the generic stub in case the specialized code cannot handle the 3313 // Jump to the generic stub in case the specialized code cannot handle the
3313 // construction. 3314 // construction.
3314 __ bind(&generic_stub_call); 3315 __ bind(&generic_stub_call);
3315 Code* code = Isolate::Current()->builtins()->builtin( 3316 Handle<Code> generic_construct_stub =
3316 Builtins::JSConstructStubGeneric); 3317 Builtins::builtin(Builtins::JSConstructStubGeneric, masm()->isolate());
3317 Handle<Code> generic_construct_stub(code);
3318 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3318 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3319 3319
3320 // Return the generated code. 3320 // Return the generated code.
3321 return GetCode(); 3321 return GetCode();
3322 } 3322 }
3323 3323
3324 3324
3325 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3325 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3326 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3326 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3327 // ----------- S t a t e ------------- 3327 // ----------- S t a t e -------------
(...skipping 253 matching lines...)
3581 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3581 __ fstp_s(Operand(edi, ebx, times_4, 0));
3582 __ ret(0); 3582 __ ret(0);
3583 } else { 3583 } else {
3584 // Perform float-to-int conversion with truncation (round-to-zero) 3584 // Perform float-to-int conversion with truncation (round-to-zero)
3585 // behavior. 3585 // behavior.
3586 3586
3587 // For the moment we make the slow call to the runtime on 3587 // For the moment we make the slow call to the runtime on
3588 // processors that don't support SSE2. The code in IntegerConvert 3588 // processors that don't support SSE2. The code in IntegerConvert
3589 // (code-stubs-ia32.cc) is roughly what is needed here though the 3589 // (code-stubs-ia32.cc) is roughly what is needed here though the
3590 // conversion failure case does not need to be handled. 3590 // conversion failure case does not need to be handled.
3591 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 3591 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3592 if (array_type != kExternalIntArray && 3592 if (array_type != kExternalIntArray &&
3593 array_type != kExternalUnsignedIntArray) { 3593 array_type != kExternalUnsignedIntArray) {
3594 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2)); 3594 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2));
3595 CpuFeatures::Scope scope(SSE2); 3595 CpuFeatures::Scope scope(SSE2);
3596 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3596 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3597 // ecx: untagged integer value 3597 // ecx: untagged integer value
3598 switch (array_type) { 3598 switch (array_type) {
3599 case kExternalPixelArray: 3599 case kExternalPixelArray:
3600 { // Clamp the value to [0..255]. 3600 { // Clamp the value to [0..255].
3601 NearLabel done; 3601 NearLabel done;
3602 __ test(ecx, Immediate(0xFFFFFF00)); 3602 __ test(ecx, Immediate(0xFFFFFF00));
3603 __ j(zero, &done); 3603 __ j(zero, &done);
3604 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3604 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3605 __ dec_b(ecx); // 0 if negative, 255 if positive. 3605 __ dec_b(ecx); // 0 if negative, 255 if positive.
3606 __ bind(&done); 3606 __ bind(&done);
3607 } 3607 }
3608 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3608 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3609 case kExternalByteArray: 3609 case kExternalByteArray:
3610 case kExternalUnsignedByteArray: 3610 case kExternalUnsignedByteArray:
3611 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3611 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3612 break; 3612 break;
3613 case kExternalShortArray: 3613 case kExternalShortArray:
3614 case kExternalUnsignedShortArray: 3614 case kExternalUnsignedShortArray:
3615 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3615 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3616 break; 3616 break;
3617 default: 3617 default:
3618 UNREACHABLE(); 3618 UNREACHABLE();
3619 break; 3619 break;
3620 } 3620 }
3621 } else { 3621 } else {
3622 if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) { 3622 if (masm()->isolate()->cpu_features()->IsSupported(SSE3)) {
3623 CpuFeatures::Scope scope(SSE3); 3623 CpuFeatures::Scope scope(SSE3);
3624 // fisttp stores values as signed integers. To represent the 3624 // fisttp stores values as signed integers. To represent the
3625 // entire range of int and unsigned int arrays, store as a 3625 // entire range of int and unsigned int arrays, store as a
3626 // 64-bit int and discard the high 32 bits. 3626 // 64-bit int and discard the high 32 bits.
3627 // If the value is NaN or +/-infinity, the result is 0x80000000, 3627 // If the value is NaN or +/-infinity, the result is 0x80000000,
3628 // which is automatically zero when taken mod 2^n, n < 32. 3628 // which is automatically zero when taken mod 2^n, n < 32.
3629 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3629 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3630 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3630 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3631 __ fisttp_d(Operand(esp, 0)); 3631 __ fisttp_d(Operand(esp, 0));
3632 __ pop(ecx); 3632 __ pop(ecx);
3633 __ add(Operand(esp), Immediate(kPointerSize)); 3633 __ add(Operand(esp), Immediate(kPointerSize));
3634 } else { 3634 } else {
3635 ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2)); 3635 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2));
3636 CpuFeatures::Scope scope(SSE2); 3636 CpuFeatures::Scope scope(SSE2);
3637 // We can easily implement the correct rounding behavior for the 3637 // We can easily implement the correct rounding behavior for the
3638 // range [0, 2^31-1]. For the time being, to keep this code simple, 3638 // range [0, 2^31-1]. For the time being, to keep this code simple,
3639 // make the slow runtime call for values outside this range. 3639 // make the slow runtime call for values outside this range.
3640 // Note: we could do better for signed int arrays. 3640 // Note: we could do better for signed int arrays.
3641 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3641 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3642 // We will need the key if we have to make the slow runtime call. 3642 // We will need the key if we have to make the slow runtime call.
3643 __ push(ecx); 3643 __ push(ecx);
3644 __ LoadPowerOf2(xmm1, ecx, 31); 3644 __ LoadPowerOf2(xmm1, ecx, 31);
3645 __ pop(ecx); 3645 __ pop(ecx);
(...skipping 32 matching lines...)
3678 3678
3679 return GetCode(flags); 3679 return GetCode(flags);
3680 } 3680 }
3681 3681
3682 3682
3683 #undef __ 3683 #undef __
3684 3684
3685 } } // namespace v8::internal 3685 } } // namespace v8::internal
3686 3686
3687 #endif // V8_TARGET_ARCH_IA32 3687 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/builtins.cc ('K') | « src/ia32/macro-assembler-ia32.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine