Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index dbbbaa7ebddc03b00ef700fe096aec74aff46e8e..e2f21c8961bb5c43fd665986726fa123fd787544 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2978,6 +2978,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { |
} |
+void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
+ class DeferredStringCharFromCode: public LDeferredCode { |
+ public: |
+ DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
+ : LDeferredCode(codegen), instr_(instr) { } |
+ virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } |
+ private: |
+ LStringCharFromCode* instr_; |
+ }; |
+ |
+ DeferredStringCharFromCode* deferred = |
+ new DeferredStringCharFromCode(this, instr); |
+ |
+ ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
+ Register char_code = ToRegister(instr->char_code()); |
+ Register result = ToRegister(instr->result()); |
+ ASSERT(!char_code.is(result)); |
+ |
+ __ cmpl(char_code, Immediate(String::kMaxAsciiCharCode)); |
+ __ j(above, deferred->entry()); |
+ __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); |
+ __ movq(result, FieldOperand(result, |
+ char_code, times_pointer_size, |
+ FixedArray::kHeaderSize)); |
+ __ CompareRoot(result, Heap::kUndefinedValueRootIndex); |
+ __ j(equal, deferred->entry()); |
+ __ bind(deferred->exit()); |
+} |
+ |
+ |
+void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { |
+ Register char_code = ToRegister(instr->char_code()); |
+ Register result = ToRegister(instr->result()); |
+ |
+ // TODO(3095996): Get rid of this. For now, we need to make the |
+ // result register contain a valid pointer because it is already |
+ // contained in the register pointer map. |
+ __ Set(result, 0); |
+ |
+ __ PushSafepointRegisters(); |
+ __ Integer32ToSmi(char_code, char_code); |
+ __ push(char_code); |
+ __ CallRuntimeSaveDoubles(Runtime::kCharFromCode); |
+ RecordSafepointWithRegisters( |
+ instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex); |
+ __ StoreToSafepointRegisterSlot(result, rax); |
+ __ PopSafepointRegisters(); |
+} |
+ |
+ |
void LCodeGen::DoStringLength(LStringLength* instr) { |
Register string = ToRegister(instr->string()); |
Register result = ToRegister(instr->result()); |